
package com.jf.cloud.order.controller.multishop;


import cn.hutool.core.collection.CollUtil;
import com.jf.cloud.api.auth.bo.UserInfoInTokenBO;
import com.jf.cloud.api.leaf.dto.SegmentDTO;
import com.jf.cloud.api.leaf.dto.SegmentItemDTO;
import com.jf.cloud.api.leaf.feign.SegmentFeignClient;
import com.jf.cloud.api.order.vo.PurchaseOrderAddrVO;
import com.jf.cloud.api.product.feign.SpuFeignClient;
import com.jf.cloud.common.constant.DistributedIdKey;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.product.vo.PurchaseSpuVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.security.AuthUserContext;
import com.jf.cloud.common.util.ExcelUtil;
import com.jf.cloud.order.dto.PurchaseOrderDTO;
import com.jf.cloud.order.dto.PurchaseOrderItemDTO;
import com.jf.cloud.order.model.PurchaseOrder;
import com.jf.cloud.order.model.PurchaseOrderAddr;
import com.jf.cloud.order.service.PurchaseOrderAddrService;
import com.jf.cloud.order.service.PurchaseOrderExcelService;
import com.jf.cloud.order.service.PurchaseOrderService;
import com.jf.cloud.order.vo.PurchaseOrderInboundExcelVO;
import com.jf.cloud.order.vo.PurchaseOrderItemVO;
import com.jf.cloud.order.vo.PurchaseOrderVO;
import com.jf.cloud.order.vo.PurchaseSpuImportVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import ma.glasnost.orika.MapperFacade;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.util.*;

/**
 * 采购订单
 *
 * @author zz
 * @date 2021-09-08 10:42:01
 */
@RestController("multishopPurchaseOrderController")
@RequestMapping("/m/purchase/order")
@Tag(name = "multishop-采购订单接口")
public class PurchaseOrderController {

    @Autowired
    private PurchaseOrderService purchaseOrderService;
    @Autowired
    private PurchaseOrderExcelService purchaseOrderExcelService;
    @Autowired
    private SegmentFeignClient segmentFeignClient;
    @Autowired
    private PurchaseOrderAddrService purchaseOrderAddrService;
    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private SpuFeignClient spuFeignClient;

    /**
     * 通过id查询
     *
     * @param purchaseOrderId id
     * @return 单个数据
     */
    @GetMapping("/info/{purchaseOrderId}")
    @Operation(summary = "根据id查询采购订单", description = "根据id查询采购订单")
    public ServerResponseEntity<PurchaseOrderVO> getById(@ParameterObject @PathVariable("purchaseOrderId") Long purchaseOrderId) {
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(purchaseOrderId, null);
        if (!Objects.equals(AuthUserContext.get().getTenantId(), purchaseOrderVO.getShopId())) {
            throw new LuckException(ResponseEnum.UNAUTHORIZED);
        }
        // 详情用户收货地址
        PurchaseOrderAddr purchaseOrderAddr = purchaseOrderAddrService.getById(purchaseOrderVO.getPurchaseOrderAddrId());
        purchaseOrderVO.setPurchaseOrderAddrVO(mapperFacade.map(purchaseOrderAddr, PurchaseOrderAddrVO.class));
        return ServerResponseEntity.success(purchaseOrderVO);
    }


    /**
     * 新增
     *
     * @param purchaseOrder
     * @return 是否新增成功
     */
    @PostMapping
//    @PreAuthorize("@pms.hasPermission('purchase:purchaseOrder:save')" )
    @Operation(summary = "新增采购订单", description = "新增采购订单")
    public ServerResponseEntity<Void> save(@RequestBody @Valid PurchaseOrderDTO purchaseOrder) {
        UserInfoInTokenBO userInfoInTokenBO = AuthUserContext.get();
        purchaseOrder.setShopId(userInfoInTokenBO.getTenantId());
        purchaseOrder.setEmployeeId(userInfoInTokenBO.getUserId());

        Map<Long, List<PurchaseOrderItemDTO>> purchaseOrderMap = new HashMap<>(purchaseOrder.getPurchaseOrderItemList().size());
        for (PurchaseOrderItemDTO purchaseOrderItem : purchaseOrder.getPurchaseOrderItemList()) {
            if (purchaseOrderItem.getPurchaseStock() <= 0) {
                throw new LuckException("请输入大于0的采购数量");
            }
            // 每个供应商的独立orderItemList
            List<PurchaseOrderItemDTO> purchaseOrderItemList = purchaseOrderMap.get(purchaseOrderItem.getSupplierId());
            if (Objects.isNull(purchaseOrderItemList)) {
                purchaseOrderItemList = new ArrayList<>();
                purchaseOrderMap.put(purchaseOrderItem.getSupplierId(), purchaseOrderItemList);
            }
            purchaseOrderItemList.add(purchaseOrderItem);
        }

        purchaseOrderMap.forEach((supplierId, purchaseOrderItemList) -> {
            PurchaseOrderDTO purchaseOrderDTO = new PurchaseOrderDTO();
            purchaseOrderDTO.setShopId(purchaseOrder.getShopId());
            purchaseOrderDTO.setSupplierId(supplierId);
            purchaseOrderDTO.setPurchaseOrderItemList(purchaseOrderItemList);
            // 获取订单号
            loadOrderDateId(purchaseOrderDTO);
            purchaseOrderDTO.setRemark(purchaseOrder.getRemark());
            purchaseOrderService.savePurchaseOrder(purchaseOrderDTO);
        });
        return ServerResponseEntity.success();
    }

    /**
     * 上传付款凭证
     *
     * @param purchaseOrder
     * @return 是否修改成功
     */
    @PutMapping("/updatePayVoucher")
    @Operation(summary = "上传付款凭证-更新订单", description = "上传付款凭证")
    public ServerResponseEntity<Void> updatePayVoucher(@RequestBody PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.updatePayVoucher(purchaseOrder);
        return ServerResponseEntity.success();
    }


    private void loadOrderDateId(PurchaseOrderDTO purchaseOrder) {
        int itemSize = purchaseOrder.getPurchaseOrderItemList().size();
        List<SegmentItemDTO> segmentItemList = new ArrayList<>();
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_ORDER, 2));
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_ORDER_ITEM, itemSize));
        segmentItemList.add(new SegmentItemDTO(DistributedIdKey.MALL4CLOUD_ORDER_ADDR, 1));

        // 获取订单id列表
        ServerResponseEntity<Map<String, List<Long>>> segmentIdResponse = segmentFeignClient.batchSegmentIdWithDateTime(new SegmentDTO(purchaseOrder.getShopId(), segmentItemList));
        if (segmentIdResponse.isFail()) {
            throw new LuckException(segmentIdResponse.getMsg());
        }

        Map<String, List<Long>> map = segmentIdResponse.getData();
        List<Long> orderIds = map.get(DistributedIdKey.MALL4CLOUD_ORDER);
        List<Long> orderItemIds = map.get(DistributedIdKey.MALL4CLOUD_ORDER_ITEM);
        List<Long> addrIds = map.get(DistributedIdKey.MALL4CLOUD_ORDER_ADDR);
        if (CollUtil.isNotEmpty(orderIds)) {
            purchaseOrder.setPurchaseOrderId(orderIds.remove(0));
        }
        if (CollUtil.isNotEmpty(addrIds)) {
            purchaseOrder.setAddrId(addrIds.get(0));
        }
        for (PurchaseOrderItemDTO purchaseOrderItemDTO : purchaseOrder.getPurchaseOrderItemList()) {
            purchaseOrderItemDTO.setPurchaseItemId(orderItemIds.remove(0));
        }
    }

    /**
     * 入库
     *
     * @param purchaseOrder
     * @return 是否修改成功
     */
    @PutMapping("/inbound")
//    @PreAuthorize("@pms.hasPermission('purchase:purchaseOrder:inbound')" )
    @Operation(summary = "入库采购订单", description = "入库采购订单")
    public ServerResponseEntity<Void> inbound(@RequestBody PurchaseOrderDTO purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.inbound(purchaseOrder);
        return ServerResponseEntity.success();
    }

    /**
     * 作废
     *
     * @param purchaseOrderId
     */
    @DeleteMapping("/nullify/{purchaseOrderId}")
//    @PreAuthorize("@pms.hasPermission('purchase:purchaseOrder:nullify')" )
    @Operation(summary = "作废采购订单", description = "作废采购订单")
    public ServerResponseEntity<Void> nullify(@PathVariable Long purchaseOrderId) {
        purchaseOrderService.nullify(AuthUserContext.get().getTenantId(), purchaseOrderId);
        return ServerResponseEntity.success();
    }

    /**
     * 完成
     *
     * @param purchaseOrder
     */
    @PutMapping("/complete")
//    @PreAuthorize("@pms.hasPermission('purchase:purchaseOrder:complete')" )
    @Operation(summary = "完成采购订单", description = "完成采购订单")
    public ServerResponseEntity<Void> finish(@RequestBody PurchaseOrder purchaseOrder) {
        purchaseOrder.setShopId(AuthUserContext.get().getTenantId());
        purchaseOrderService.complete(AuthUserContext.get().getTenantId(), purchaseOrder.getPurchaseOrderId());
        return ServerResponseEntity.success();
    }

    /**
     * 下载模板
     *
     * @param response
     */
    @GetMapping(value = "/download_model")
    @ResponseBody
    @Operation(summary = "下载导入采购商品模板", description = "下载导入采购商品模板")
    public void downloadModel(HttpServletResponse response) {
        purchaseOrderService.downloadModel(response);
    }

    /**
     * 导入文件
     */
    @PostMapping("/export_excel")
    @ResponseBody
    @Operation(summary = "导入采购商品", description = "导入采购商品")
    public ServerResponseEntity<PurchaseSpuImportVO> exportExcel(@RequestParam("excelFile") MultipartFile excelFile) {
        if (excelFile == null) {
            // 网络繁忙，请稍后重试
            throw new LuckException("网络繁忙，请稍后重试");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        return ServerResponseEntity.success(purchaseOrderService.parseFile(excelFile, shopId));
    }

    @GetMapping("/inbound/export")
    @Schema(description = "导出入库商品")
    public void export(@ParameterObject @RequestParam("purchaseOrderId") Long purchaseOrderId, HttpServletResponse response) {
        List<PurchaseOrderInboundExcelVO> purchaseOrderInboundExcelList = new ArrayList<>();
        if (Objects.equals(purchaseOrderId, 0L)) {
            purchaseOrderInboundExcelList.add(new PurchaseOrderInboundExcelVO());
            ExcelUtil.soleExcel(response, purchaseOrderInboundExcelList, PurchaseOrderInboundExcelVO.EXCEL_NAME, PurchaseOrderInboundExcelVO.MERGE_ROW_INDEX,
                    PurchaseOrderInboundExcelVO.MERGE_COLUMN_INDEX, PurchaseOrderInboundExcelVO.class);
            return;
        }
        PurchaseOrderVO purchaseOrderVO = purchaseOrderService.info(purchaseOrderId, null);
//        purchaseOrderInboundExcelList = mapperFacade.mapAsList(purchaseOrderVO.getPurchaseOrderItemList(), PurchaseOrderInboundExcelVO.class);
        int index = 0;
        for (PurchaseOrderItemVO purchaseOrderItemVO : purchaseOrderVO.getPurchaseOrderItemList()) {
            PurchaseOrderInboundExcelVO purchaseOrderInboundExcelVO = new PurchaseOrderInboundExcelVO();
            purchaseOrderInboundExcelVO.setPartyCode(purchaseOrderItemVO.getPartyCode());
            purchaseOrderInboundExcelVO.setSpuName(purchaseOrderItemVO.getSpuName());
            purchaseOrderInboundExcelVO.setPurchaseStock(purchaseOrderItemVO.getPurchaseStock());
            purchaseOrderInboundExcelVO.setActualStock(purchaseOrderItemVO.getPurchaseStock() - purchaseOrderItemVO.getActualStock());
            purchaseOrderInboundExcelVO.setBeDeliveredNum(purchaseOrderItemVO.getPurchaseStock() - purchaseOrderItemVO.getActualStock());
            purchaseOrderInboundExcelList.add(purchaseOrderInboundExcelVO);
        }
//        for (PurchaseOrderInboundExcelVO purchaseOrderInboundExcelVO : purchaseOrderInboundExcelList) {
//            purchaseOrderInboundExcelVO.setSeq(String.valueOf(index));
//            purchaseOrderInboundExcelVO.setBeDeliveredNum(purchaseOrderInboundExcelVO.getPurchaseStock() - purchaseOrderInboundExcelVO.getActualStock());
//            purchaseOrderInboundExcelVO.setActualStock(purchaseOrderInboundExcelVO.getPurchaseStock() - purchaseOrderInboundExcelVO.getBeDeliveredNum());
//            index++;
//        }
        ExcelUtil.soleExcel(response, purchaseOrderInboundExcelList, PurchaseOrderInboundExcelVO.EXCEL_NAME, PurchaseOrderInboundExcelVO.MERGE_ROW_INDEX,
                PurchaseOrderInboundExcelVO.MERGE_COLUMN_INDEX, PurchaseOrderInboundExcelVO.class);
    }


    /**
     * 导入入库文件
     */
    @PostMapping("/inbound/exportExcel/{purchaseOrderId}")
    @ResponseBody
    @Schema(description = "导入入库文件")
    public ServerResponseEntity<List<PurchaseOrderItemVO>> inboundExportExcel(@RequestParam("excelFile") MultipartFile excelFile, @PathVariable Long purchaseOrderId) throws Exception {
        if (excelFile == null) {
            // 网络繁忙，请稍后重试
            throw new LuckException("网络繁忙，请稍后重试");
        }
        Long shopId = AuthUserContext.get().getTenantId();
        List<PurchaseOrderItemVO> excelInfoVO = purchaseOrderExcelService.inboundParseFile(excelFile, shopId, purchaseOrderId);
        return ServerResponseEntity.success(excelInfoVO);
    }

}
